// AOT缓存实现
// 提供预编译代码的缓存机制，加快冷启动时间

#[cfg(feature = "jit")]
use std::collections::{HashMap, HashSet};
#[cfg(feature = "jit")]
use std::fs::{self, File};
#[cfg(feature = "jit")]
use std::io::{Read, Write};
#[cfg(feature = "jit")]
use std::path::{Path, PathBuf};
#[cfg(feature = "jit")]
use std::sync::{Arc, Mutex, RwLock};
#[cfg(feature = "jit")]
use std::time::{Duration, Instant, SystemTime};

#[cfg(feature = "jit")]
use crate::error::{PipitError, Result};
#[cfg(feature = "jit")]
use crate::jit::{PipitJIT, JITOptimizationLevel};

#[cfg(feature = "jit")]
/// AOT缓存配置
#[derive(Debug, Clone)]
pub struct AOTCacheConfig {
    pub enabled: bool,
    pub cache_dir: PathBuf,
    pub max_cache_size_mb: u64,
    pub cache_ttl: Duration,
    pub compression: bool,
}

#[cfg(feature = "jit")]
impl Default for AOTCacheConfig {
    fn default() -> Self {
        let cache_dir = std::env::temp_dir().join("pipit_aot_cache");
        AOTCacheConfig {
            enabled: true,
            cache_dir,
            max_cache_size_mb: 256, // 默认最大256MB
            cache_ttl: std::time::Duration::from_secs(7 * 24 * 60 * 60), // 默认缓存7天
            compression: false,
        }
    }
}

#[cfg(feature = "jit")]
/// 缓存条目元数据
#[derive(Debug, Clone, PartialEq, Eq)]
struct CacheEntryMetadata {
    module_name: String,
    timestamp: u64,
    size_bytes: u64,
    optimization_level: JITOptimizationLevel,
    source_hash: String,
    compiler_version: String,
}

#[cfg(feature = "jit")]
/// AOT缓存管理器
pub struct AOTCacheManager {
    config: AOTCacheConfig,
    cached_modules: Arc<RwLock<HashMap<String, Vec<u8>>>>,
    metadata: Arc<RwLock<HashMap<String, CacheEntryMetadata>>>,
    loaded_modules: Arc<Mutex<HashSet<String>>>,
    total_cache_size: Arc<Mutex<u64>>,
}

#[cfg(feature = "jit")]
impl AOTCacheManager {
    /// 创建新的AOT缓存管理器
    pub fn new(config: AOTCacheConfig) -> Result<Self> {
        let manager = AOTCacheManager {
            config: config.clone(),
            cached_modules: Arc::new(RwLock::new(HashMap::new())),
            metadata: Arc::new(RwLock::new(HashMap::new())),
            loaded_modules: Arc::new(Mutex::new(HashSet::new())),
            total_cache_size: Arc::new(Mutex::new(0)),
        };
        
        // 初始化缓存目录
        if config.enabled {
            manager.initialize_cache_dir()?;
            manager.load_cache_metadata()?;
            manager.cleanup_expired_cache()?;
            manager.enforce_cache_size_limit()?;
        }
        
        Ok(manager)
    }
    
    /// 初始化缓存目录
    fn initialize_cache_dir(&self) -> Result<()> {
        if !self.config.cache_dir.exists() {
            fs::create_dir_all(&self.config.cache_dir)?;
        }
        Ok(())
    }
    
    /// 加载缓存元数据
    fn load_cache_metadata(&self) -> Result<()> {
        if !self.config.enabled {
            return Ok(());
        }
        
        let entries = fs::read_dir(&self.config.cache_dir)?;
        for entry in entries {
            let entry = entry?;
            let path = entry.path();
            
            // 跳过非文件项
            if !path.is_file() {
                continue;
            }
            
            // 只处理.metadata文件
            if let Some(ext) = path.extension() {
                if ext != "metadata" {
                    continue;
                }
            } else {
                continue;
            }
            
            // 读取元数据
            let module_name = path.file_stem()
                .and_then(|stem| stem.to_str())
                .ok_or_else(|| PipitError::RuntimeError("Invalid cache file name".to_string()))?;
            
            let metadata = self.read_metadata_file(&path)?;
            self.metadata.write().unwrap().insert(module_name.to_string(), metadata);
        }
        
        Ok(())
    }
    
    /// 读取元数据文件
    fn read_metadata_file(&self, path: &Path) -> Result<CacheEntryMetadata> {
        let mut file = File::open(path)?;
        let mut contents = String::new();
        file.read_to_string(&mut contents)?;
        
        // 简单解析元数据（实际实现中可以使用serde_json等）
        let lines: Vec<&str> = contents.lines().collect();
        
        let module_name = lines.get(0).ok_or_else(|| 
            PipitError::RuntimeError("Invalid metadata format".to_string()))?
            .split(":").nth(1).ok_or_else(|| 
            PipitError::RuntimeError("Invalid metadata format".to_string()))?
            .trim().to_string();
        
        let timestamp = lines.get(1).ok_or_else(|| 
            PipitError::RuntimeError("Invalid metadata format".to_string()))?
            .split(":").nth(1).ok_or_else(|| 
            PipitError::RuntimeError("Invalid metadata format".to_string()))?
            .trim().parse::<u64>().map_err(|_| 
            PipitError::RuntimeError("Invalid timestamp format".to_string()))?;
        
        let size_bytes = lines.get(2).ok_or_else(|| 
            PipitError::RuntimeError("Invalid metadata format".to_string()))?
            .split(":").nth(1).ok_or_else(|| 
            PipitError::RuntimeError("Invalid metadata format".to_string()))?
            .trim().parse::<u64>().map_err(|_| 
            PipitError::RuntimeError("Invalid size format".to_string()))?;
        
        let optimization_level_str = lines.get(3).ok_or_else(|| 
            PipitError::RuntimeError("Invalid metadata format".to_string()))?
            .split(":").nth(1).ok_or_else(|| 
            PipitError::RuntimeError("Invalid metadata format".to_string()))?
            .trim();
        
        let optimization_level = match optimization_level_str {
            "None" => JITOptimizationLevel::None,
            "Basic" => JITOptimizationLevel::Basic,
            "Aggressive" => JITOptimizationLevel::Aggressive,
            _ => return Err(PipitError::RuntimeError("Invalid optimization level".to_string())),
        };
        
        let source_hash = lines.get(4).ok_or_else(|| 
            PipitError::RuntimeError("Invalid metadata format".to_string()))?
            .split(":").nth(1).ok_or_else(|| 
            PipitError::RuntimeError("Invalid metadata format".to_string()))?
            .trim().to_string();
        
        let compiler_version = lines.get(5).ok_or_else(|| 
            PipitError::RuntimeError("Invalid metadata format".to_string()))?
            .split(":").nth(1).ok_or_else(|| 
            PipitError::RuntimeError("Invalid metadata format".to_string()))?
            .trim().to_string();
        
        Ok(CacheEntryMetadata {
            module_name,
            timestamp,
            size_bytes,
            optimization_level,
            source_hash,
            compiler_version,
        })
    }
    
    /// 清理过期的缓存
    fn cleanup_expired_cache(&self) -> Result<()> {
        if !self.config.enabled {
            return Ok(());
        }
        
        let current_time = SystemTime::now()
            .duration_since(SystemTime::UNIX_EPOCH)
            .map_err(|_| PipitError::RuntimeError("Time error".to_string()))?
            .as_secs();
        
        let metadata = self.metadata.read().unwrap().clone();
        for (module_name, meta) in metadata.iter() {
            if meta.timestamp < current_time {
                self.remove_cached_module(module_name)?;
            }
        }
        
        Ok(())
    }
    
    /// 强制执行缓存大小限制
    fn enforce_cache_size_limit(&self) -> Result<()> {
        if !self.config.enabled {
            return Ok(());
        }
        
        let max_size_bytes = self.config.max_cache_size_mb * 1024 * 1024;
        let mut total_size = *self.total_cache_size.lock().unwrap();
        
        if total_size > max_size_bytes {
            // 获取所有缓存条目并按时间戳排序
            let metadata = self.metadata.read().unwrap().clone();
            let mut sorted_entries: Vec<(&String, &CacheEntryMetadata)> = 
                metadata.iter().collect();
            
            sorted_entries.sort_by(|a, b| a.1.timestamp.cmp(&b.1.timestamp));
            
            // 删除最旧的条目直到总大小在限制内
            for (module_name, meta) in sorted_entries {
                if total_size <= max_size_bytes {
                    break;
                }
                
                self.remove_cached_module(module_name)?;
                total_size -= meta.size_bytes;
            }
            
            *self.total_cache_size.lock().unwrap() = total_size;
        }
        
        Ok(())
    }
    
    /// 计算源代码的哈希值
    pub fn calculate_source_hash(source: &str) -> String {
        use std::collections::hash_map::DefaultHasher;
        use std::hash::Hasher;
        
        let mut hasher = DefaultHasher::new();
        hasher.write(source.as_bytes());
        format!("{:x}", hasher.finish())
    }
    
    /// 检查模块是否在缓存中
    pub fn is_module_cached(&self, module_name: &str, source_hash: &str, 
                          optimization_level: JITOptimizationLevel) -> bool {
        if !self.config.enabled {
            return false;
        }
        
        if let Some(meta) = self.metadata.read().unwrap().get(module_name) {
            return meta.source_hash == source_hash && 
                   meta.optimization_level == optimization_level;
        }
        
        false
    }
    
    /// 从缓存加载模块
    pub fn load_module_from_cache(&self, module_name: &str) -> Result<Option<Vec<u8>>> {
        if !self.config.enabled {
            return Ok(None);
        }
        
        // 检查是否已经加载
        {    
            let loaded = self.loaded_modules.lock().unwrap();
            if loaded.contains(module_name) {
                if let Some(data) = self.cached_modules.read().unwrap().get(module_name) {
                    return Ok(Some(data.clone()));
                }
            }
        }
        
        // 检查元数据
        if !self.metadata.read().unwrap().contains_key(module_name) {
            return Ok(None);
        }
        
        // 读取缓存文件
        let cache_path = self.config.cache_dir.join(format!("{}.cache", module_name));
        if !cache_path.exists() {
            return Ok(None);
        }
        
        let data = fs::read(&cache_path)?;
        
        // 更新内存缓存
        self.cached_modules.write().unwrap().insert(module_name.to_string(), data.clone());
        self.loaded_modules.lock().unwrap().insert(module_name.to_string());
        
        Ok(Some(data))
    }
    
    /// 将模块保存到缓存
    pub fn save_module_to_cache(&self, module_name: &str, data: &[u8], 
                              source_hash: &str, optimization_level: JITOptimizationLevel) -> Result<()> {
        if !self.config.enabled {
            return Ok(());
        }
        
        // 检查空间限制
        let new_size = data.len() as u64;
        let max_size_bytes = self.config.max_cache_size_mb * 1024 * 1024;
        
        let mut total_size = self.total_cache_size.lock().unwrap();
        if *total_size + new_size > max_size_bytes {
            self.enforce_cache_size_limit()?;
            // 再次检查，因为可能还是不够空间
            if *total_size + new_size > max_size_bytes {
                return Err(PipitError::RuntimeError("Cache size limit exceeded".to_string()));
            }
        }
        
        // 保存缓存文件
        let cache_path = self.config.cache_dir.join(format!("{}.cache", module_name));
        fs::write(&cache_path, data)?;
        
        // 保存元数据
        let metadata = CacheEntryMetadata {
            module_name: module_name.to_string(),
            timestamp: SystemTime::now()
                .duration_since(SystemTime::UNIX_EPOCH)
                .map_err(|_| PipitError::RuntimeError("Time error".to_string()))?
                .as_secs(),
            size_bytes: new_size,
            optimization_level,
            source_hash: source_hash.to_string(),
            compiler_version: "1.0.0".to_string(), // 实际应该使用真实版本号
        };
        
        let metadata_path = self.config.cache_dir.join(format!("{}.metadata", module_name));
        self.write_metadata_file(&metadata_path, &metadata)?;
        
        // 更新内存缓存
        self.cached_modules.write().unwrap().insert(module_name.to_string(), data.to_vec());
        self.metadata.write().unwrap().insert(module_name.to_string(), metadata);
        *total_size += new_size;
        
        Ok(())
    }
    
    /// 写入元数据文件
    fn write_metadata_file(&self, path: &Path, metadata: &CacheEntryMetadata) -> Result<()> {
        let mut file = File::create(path)?;
        
        writeln!(file, "module_name: {}", metadata.module_name)?;
        writeln!(file, "timestamp: {}", metadata.timestamp)?;
        writeln!(file, "size_bytes: {}", metadata.size_bytes)?;
        writeln!(file, "optimization_level: {:?}", metadata.optimization_level)?;
        writeln!(file, "source_hash: {}", metadata.source_hash)?;
        writeln!(file, "compiler_version: {}", metadata.compiler_version)?;
        
        Ok(())
    }
    
    /// 移除缓存的模块
    pub fn remove_cached_module(&self, module_name: &str) -> Result<()> {
        if !self.config.enabled {
            return Ok(());
        }
        
        // 删除缓存文件
        let cache_path = self.config.cache_dir.join(format!("{}.cache", module_name));
        if cache_path.exists() {
            fs::remove_file(&cache_path)?;
        }
        
        // 删除元数据文件
        let metadata_path = self.config.cache_dir.join(format!("{}.metadata", module_name));
        if metadata_path.exists() {
            fs::remove_file(&metadata_path)?;
        }
        
        // 更新内存缓存
        if let Some(meta) = self.metadata.write().unwrap().remove(module_name) {
            self.cached_modules.write().unwrap().remove(module_name);
            self.loaded_modules.lock().unwrap().remove(module_name);
            
            let mut total_size = self.total_cache_size.lock().unwrap();
            *total_size -= meta.size_bytes;
        }
        
        Ok(())
    }
    
    /// 清除所有缓存
    pub fn clear_cache(&self) -> Result<()> {
        if !self.config.enabled {
            return Ok(());
        }
        
        // 删除缓存目录下所有文件
        if self.config.cache_dir.exists() {
            for entry in fs::read_dir(&self.config.cache_dir)? {
                let entry = entry?;
                let path = entry.path();
                if path.is_file() {
                    fs::remove_file(path)?;
                }
            }
        }
        
        // 清空内存缓存
        self.cached_modules.write().unwrap().clear();
        self.metadata.write().unwrap().clear();
        self.loaded_modules.lock().unwrap().clear();
        *self.total_cache_size.lock().unwrap() = 0;
        
        Ok(())
    }
    
    /// 获取缓存统计信息
    pub fn get_cache_stats(&self) -> (usize, u64) {
        let count = self.metadata.read().unwrap().len();
        let size = *self.total_cache_size.lock().unwrap();
        (count, size)
    }
}